package mao.concurent.consumer;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Totoro
 * @date 2020/7/8
 * @explain:  手写一个concurrentQueue
 */

//避免和类库同名
public class MyConcurrentQueue<T>   {

    private Queue<T> queue = new LinkedList<>();
    private Lock lock = new ReentrantLock();
    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();
    int count = 0;
    int max = 10;
    public MyConcurrentQueue(int max) {
        this.max = max;
    }

    public void put(T i){
        lock.lock();

        try{
            while (count == max){
                notFull.await();
            }
            queue.add(i);
            count++;
            notEmpty.signal();
        }catch (InterruptedException e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            lock.unlock();
        }
    }

    public T get(){
        lock.lock();
        try{
            while (count == 0){
                notEmpty.await();
            }
            count--;
            T i =  queue.poll();
            notFull.signal();
            return i;
        }catch (InterruptedException e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            lock.unlock();
        }
    }
}
